home *** CD-ROM | disk | FTP | other *** search
- // Some routines for loading PCX files
-
- #include <stdio.h>
- #include <dos.h>
- #include <io.h>
- #include <fcntl.h>
- #include <mem.h>
-
- #include "pcx.h"
-
- const long IMAGE_SIZE=64000; // Size of PCX bitmap
-
- int Pcx::load(char far *filename,pcx_struct *pcx)
- {
-
- // Function to load PCX data from file FILENAME into
- // structure PCX.
-
- // Open file; return nonzero value on error
-
- if ((infile=open(filename,O_BINARY))==NULL)
- return(-1);
-
- // Move file pointer to start of header:
-
- lseek(infile,0L,SEEK_SET);
-
- // Reader header from PCX file:
-
- int readlen=read(infile,&(pcx->header),
- sizeof(pcx_header));
-
- // Decompress bitmap and place in buffer,
- // returning non-zero value if error occurs:
-
- if (!load_image(infile,pcx)) return(-1);
-
- // Decompress palette and store in array:
-
- load_palette(infile,pcx);
-
- close(infile); // Close PCX file
- return(0); // Return non-error condition
- }
-
- int Pcx::load_image(int pcxfile,pcx_struct *pcx)
-
- // Decompress bitmap and store in buffer
-
- {
- // Symbolic constants for encoding modes, with
- // BYTEMODE representing uncompressed byte mode
- // and RUNMODE representing run-length encoding mode:
-
- const int BYTEMODE=0, RUNMODE=1;
-
- // Buffer for data read from disk:
-
- const int BUFLEN=5*1024;
- int mode=BYTEMODE; // Current encoding mode being used,
- // initially set to BYTEMODE
- int readlen; // Number of characters read from file
- static unsigned char outbyte; // Next byte for buffer
- static unsigned char bytecount; // Counter for runs
- static unsigned char buffer[BUFLEN]; // Disk read buffer
-
- // Allocate memory for bitmap buffer and return -1 if
- // an error occurs:
-
- if ((pcx->image=new unsigned char[IMAGE_SIZE])==NULL)
- return(-1);
- int bufptr=0; // Point to start of buffer
- readlen=0; // Zero characters read so far
-
- // Create pointer to start of image:
-
- unsigned char *image_ptr=pcx->image;
-
- // Loop for entire length of bitmap buffer:
-
- for (long i=0; i<IMAGE_SIZE; i++) {
- if (mode==BYTEMODE) { // If we're in individual byte
- // mode....
- if (bufptr>=readlen) { // If past end of buffer...
- bufptr=0; // Point to start
-
- // Read more bytes from file into buffer;
- // if no more bytes left, break out of loop
-
- if ((readlen=read(pcxfile,buffer,BUFLEN))==0)
- break;
- }
- outbyte=buffer[bufptr++]; // Next byte of bitmap
- if (outbyte>0xbf) { // If run-length flag...
-
- // Calculate number of bytes in run:
-
- bytecount = (int)((int)outbyte & 0x3f);
- if (bufptr>=readlen) { // If past end of buffer
- bufptr=0; // Point to start
-
- // Read more bytes from file into buffer;
- // if no more bytes left, break out of loop
-
- if ((readlen=read(pcxfile,buffer,BUFLEN))==0)
- break;
- }
- outbyte=buffer[bufptr++]; // Next byte of bitmap
-
- // Switch to run-length mode:
-
- if (--bytecount > 0) mode = RUNMODE;
- }
- }
-
- // Switch to individual byte mode:
-
- else if (--bytecount == 0) mode=BYTEMODE;
-
- // Add next byte to bitmap buffer:
-
- *image_ptr++=outbyte;
- }
- }
-
- void Pcx::load_palette(int pcxfile,pcx_struct *pcx)
-
- // Load color register values from file into palette array
-
- {
-
- // Seek to start of palette, which is always 768 bytes
- // from end of file:
-
- lseek(pcxfile,-768L,SEEK_END);
-
- // Read all 768 bytes of palette into array:
-
- read(pcxfile,pcx->palette,3*256);
-
- // Adjust for required bit shift:
-
- for (int i=0; i<256; i++)
- for (int j=0; j<3; j++)
- pcx->palette[i*3+j]=pcx->palette[i*3+j]>>2;
- }
-